/**
 * XappTool React SDK
 * 免邀请安装归因 SDK
 * 类似 xinstall/openinstall/sharetrace 功能
 * @version 1.0.0
 */

import { useState, useEffect, useCallback, useRef } from 'react';

// 工具函数
const Utils = {
  // 生成唯一ID
  generateUUID() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
      const r = Math.random() * 16 | 0;
      const v = c === 'x' ? r : (r & 0x3 | 0x8);
      return v.toString(16);
    });
  },

  // 生成设备指纹
  generateDeviceFingerprint() {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    
    // Canvas 指纹
    ctx.textBaseline = 'top';
    ctx.font = '14px Arial';
    ctx.fillStyle = '#f60';
    ctx.fillRect(125, 1, 62, 20);
    ctx.fillStyle = '#069';
    ctx.fillText('Canvas fingerprint 🎨', 2, 15);
    
    const canvasData = canvas.toDataURL();
    
    // 收集设备信息
    const info = {
      userAgent: navigator.userAgent,
      language: navigator.language,
      languages: navigator.languages ? navigator.languages.join(',') : '',
      platform: navigator.platform,
      cookieEnabled: navigator.cookieEnabled,
      doNotTrack: navigator.doNotTrack,
      screenResolution: `${screen.width}x${screen.height}`,
      screenColorDepth: screen.colorDepth,
      timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
      canvas: canvasData,
      webgl: this.getWebGLFingerprint(),
      audio: this.getAudioFingerprint(),
      fonts: this.getFontsFingerprint(),
      plugins: this.getPluginsFingerprint(),
      localStorage: !!window.localStorage,
      sessionStorage: !!window.sessionStorage,
      indexedDB: !!window.indexedDB,
      openDatabase: !!window.openDatabase,
      cpuClass: navigator.cpuClass || '',
      hardwareConcurrency: navigator.hardwareConcurrency || 0,
      maxTouchPoints: navigator.maxTouchPoints || 0,
      touchSupport: 'ontouchstart' in window,
      deviceMemory: navigator.deviceMemory || 0
    };
    
    // 生成哈希
    const fingerprintString = JSON.stringify(info);
    return this.sha256(fingerprintString);
  },

  // WebGL 指纹
  getWebGLFingerprint() {
    try {
      const canvas = document.createElement('canvas');
      const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
      if (!gl) return '';
      const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
      const vendor = debugInfo ? gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL) : '';
      const renderer = debugInfo ? gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL) : '';
      return `${vendor}~${renderer}`;
    } catch (e) {
      return '';
    }
  },

  // 音频指纹（简化）
  getAudioFingerprint() {
    try {
      const audioContext = new (window.AudioContext || window.webkitAudioContext)();
      const oscillator = audioContext.createOscillator();
      const analyser = audioContext.createAnalyser();
      const gainNode = audioContext.createGain();
      const scriptProcessor = audioContext.createScriptProcessor(4096, 1, 1);
      oscillator.type = 'triangle';
      oscillator.frequency.setValueAtTime(10000, audioContext.currentTime);
      gainNode.gain.setValueAtTime(0, audioContext.currentTime);
      oscillator.connect(analyser);
      analyser.connect(scriptProcessor);
      scriptProcessor.connect(gainNode);
      gainNode.connect(audioContext.destination);
      return new Promise((resolve) => {
        scriptProcessor.onaudioprocess = function(bins) {
          const data = bins.inputBuffer.getChannelData(0);
          let sum = 0;
          for (let i = 0; i < data.length; i++) sum += Math.abs(data[i]);
          resolve(sum.toString());
        };
        oscillator.start(0);
        setTimeout(() => { oscillator.stop(); audioContext.close(); resolve(''); }, 100);
      });
    } catch (e) {
      return Promise.resolve('');
    }
  },

  // 字体指纹（简化）
  getFontsFingerprint() {
    try {
      const fonts = ['Arial','Verdana','Tahoma','Times New Roman','Courier New'];
      const availableFonts = [];
      const testString = 'mmmmmmmmmmlli';
      const testSize = '72px';
      const h = document.body;
      const baseFonts = ['monospace','sans-serif','serif'];
      const testElement = document.createElement('span');
      testElement.style.position = 'absolute';
      testElement.style.left = '-9999px';
      testElement.style.fontSize = testSize;
      testElement.innerHTML = testString;
      for (const baseFont of baseFonts) {
        testElement.style.fontFamily = baseFont;
        h.appendChild(testElement);
        const defaultWidth = testElement.offsetWidth;
        const defaultHeight = testElement.offsetHeight;
        h.removeChild(testElement);
        for (const font of fonts) {
          testElement.style.fontFamily = font + ',' + baseFont;
          h.appendChild(testElement);
          const width = testElement.offsetWidth;
          const height = testElement.offsetHeight;
          h.removeChild(testElement);
          if (width !== defaultWidth || height !== defaultHeight) availableFonts.push(font);
        }
      }
      return availableFonts.join(',');
    } catch (e) {
      return '';
    }
  },

  // 插件指纹（简化）
  getPluginsFingerprint() {
    if (!navigator.plugins || !navigator.plugins.length) return '';
    const plugins = [];
    for (let i = 0; i < navigator.plugins.length; i++) {
      const plugin = navigator.plugins[i];
      plugins.push(plugin.name + '~' + plugin.description);
    }
    return plugins.join(';');
  },

  // 哈希函数
  hashCode(str) {
    let hash = 0;
    if (str.length === 0) return hash;
    for (let i = 0; i < str.length; i++) {
      const char = str.charCodeAt(i);
      hash = ((hash << 5) - hash) + char;
      hash = hash & hash;
    }
    return Math.abs(hash).toString(36);
  },

  // 防抖函数
  debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
      const later = () => {
        clearTimeout(timeout);
        func(...args);
      };
      clearTimeout(timeout);
      timeout = setTimeout(later, wait);
    };
  },

  // 节流函数
  throttle(func, limit) {
    let inThrottle;
    return function() {
      const args = arguments;
      const context = this;
      if (!inThrottle) {
        func.apply(context, args);
        inThrottle = true;
        setTimeout(() => inThrottle = false, limit);
      }
    };
  },

  // 深度克隆
  deepClone(obj) {
    if (obj === null || typeof obj !== 'object') return obj;
    if (obj instanceof Date) return new Date(obj.getTime());
    if (obj instanceof Array) return obj.map(item => this.deepClone(item));
    if (typeof obj === 'object') {
      const cloned = {};
      for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
          cloned[key] = this.deepClone(obj[key]);
        }
      }
      return cloned;
    }
  },

  // 获取URL参数
  getUrlParams() {
    const params = {};
    const searchParams = new URLSearchParams(window.location.search);
    
    for (const [key, value] of searchParams) {
      params[key] = value;
    }
    
    return params;
  }
};

// XappTool SDK 类
class XappToolReact {
  constructor(options = {}) {
    this.config = {
      apiKey: '',
      apiUrl: 'https://api.xapptool.cn',
      timeout: 5000,
      debug: false,
      environment: 'production',
      fingerprint: {
        include: [],
        exclude: [],
        customData: {},
        privacyMode: false
      },
      performance: {
        enableCache: true,
        cacheTimeout: 3600000,
        enableCompression: true,
        batchRequests: false,
        batchSize: 10,
        batchInterval: 5000
      },
      privacy: {
        gdpr: { enabled: false },
        ccpa: { enabled: false },
        cookieConsent: { enabled: false }
      },
      cors: {
        enabled: false,
        proxy: '',
        jsonp: false
      },
      ...options
    };
    
    this.isInitialized = false;
    this.deviceFingerprint = '';
    this.sessionId = Utils.generateUUID();
    this.cache = new Map();
    this.requestQueue = [];
    this.eventListeners = {};
    
    this.initFingerprint();
  }

  /**
   * 初始化 SDK
   */
  async init(options = {}) {
    try {
      this.config = { ...this.config, ...options };
      
      if (!this.config.apiKey) {
        throw new Error('API Key is required');
      }
      
      this.log('Initializing XappTool React SDK...');
      
      // 生成设备指纹
      this.deviceFingerprint = await this.generateFingerprint();
      
      // 检查隐私合规
      if (this.config.privacy.gdpr.enabled || this.config.privacy.ccpa.enabled) {
        await this.checkPrivacyCompliance();
      }
      
      // 检查浏览器兼容性
      this.checkBrowserCompatibility();
      
      // 启动性能监控
      if (this.config.performance.enableCache) {
        this.startCacheCleanup();
      }
      
      // 启动批量请求处理
      if (this.config.performance.batchRequests) {
        this.startBatchProcessor();
      }
      
      this.isInitialized = true;
      this.emit('ready', { deviceFingerprint: this.deviceFingerprint });
      
      this.log('XappTool React SDK initialized successfully');
      return { success: true, deviceFingerprint: this.deviceFingerprint };
      
    } catch (error) {
      this.log('SDK initialization failed:', error);
      this.emit('error', error);
      throw error;
    }
  }

  /**
   * 生成设备指纹
   */
  async generateFingerprint() {
    try {
      // 检查缓存
      const cacheKey = 'device_fingerprint';
      if (this.config.performance.enableCache) {
        const cached = this.getCache(cacheKey);
        if (cached) return cached;
      }
      
      let fingerprint = await Utils.generateDeviceFingerprint();
      
      // 添加自定义数据
      if (this.config.fingerprint.customData) {
        const customString = JSON.stringify(this.config.fingerprint.customData);
        fingerprint += Utils.hashCode(customString);
      }
      
      // 缓存指纹
      if (this.config.performance.enableCache) {
        this.setCache(cacheKey, fingerprint, this.config.performance.cacheTimeout);
      }
      
      return fingerprint;
    } catch (error) {
      this.log('Fingerprint generation failed:', error);
      return Utils.generateUUID(); // 回退方案
    }
  }

  /**
   * 获取安装参数
   */
  async getInstallParams() {
    if (!this.isInitialized) {
      throw new Error('SDK not initialized');
    }
    
    try {
      // 检查缓存
      const cacheKey = 'install_params_' + this.deviceFingerprint;
      if (this.config.performance.enableCache) {
        const cached = this.getCache(cacheKey);
        if (cached) return cached;
      }
      
      // 获取当前URL参数
      const urlParams = Utils.getUrlParams();
      
      // 构建请求数据
      const requestData = {
        apiKey: this.config.apiKey,
        deviceFingerprint: this.deviceFingerprint,
        sessionId: this.sessionId,
        url: window.location.href,
        referrer: document.referrer,
        userAgent: navigator.userAgent,
        timestamp: Date.now(),
        urlParams: urlParams,
        fingerprint: this.deviceFingerprint
      };
      
      // 发送归因请求
      const response = await this.request('/api/v1/attribution', requestData);
      
      const installParams = {
        inviter: response.data.inviter || null,
        channel: response.data.channel || null,
        params: response.data.params || {},
        utm: response.data.utm || {},
        attributionType: response.data.attributionType || 'organic',
        method: response.data.attributionType || 'organic',
        confidence: response.data.confidence || 0,
        timestamp: response.data.timestamp || Date.now()
      };
      
      // 缓存结果
      if (this.config.performance.enableCache) {
        this.setCache(cacheKey, installParams, this.config.performance.cacheTimeout);
      }
      
      return installParams;
      
    } catch (error) {
      this.log('Failed to get install params:', error);
      
      // 返回默认参数
      return {
        inviter: null,
        channel: null,
        params: {},
        utm: Utils.getUrlParams(),
        attributionType: 'organic',
        method: 'organic',
        confidence: 0,
        timestamp: Date.now()
      };
    }
  }

  /**
   * 生成邀请链接
   */
  async generateInvitationLink(options = {}) {
    if (!this.isInitialized) {
      throw new Error('SDK not initialized');
    }
    
    try {
      const {
        userId = '',
        code = '',
        channel = 'direct',
        params = {},
        expireDays = 7
      } = options;
      
      const requestData = {
        apiKey: this.config.apiKey,
        userId: userId,
        code: code || Utils.generateUUID().substr(0, 8),
        channel: channel,
        params: params,
        expireDays: expireDays,
        deviceFingerprint: this.deviceFingerprint
      };
      
      const response = await this.request('/api/v1/invitation-link', requestData);
      
      return response.data.invitationLink;
      
    } catch (error) {
      this.log('Failed to generate invitation link:', error);
      
      // 生成默认链接
      const baseUrl = window.location.origin + window.location.pathname;
      const params = new URLSearchParams({
        inviter: options.userId || '',
        code: options.code || Utils.generateUUID().substr(0, 8),
        channel: options.channel || 'direct',
        ...options.params
      });
      
      return baseUrl + '?' + params.toString();
    }
  }

  getShareUrl(config = {}, params = {}, type = 'auto') {
    const base = (type === 'custom' || config.is_custom_landing) ? `/lp/custom/${config.id}` : `/lp/${config.id}`
    const qs = new URLSearchParams(params).toString()
    return qs ? `${base}?${qs}` : base
  }

  /**
   * 反作弊检测
   */
  async checkAntiFraud() {
    const ua = navigator.userAgent.toLowerCase();
    const isHeadless = !!navigator.webdriver || !navigator.plugins || !navigator.plugins.length;
    const botKeywords = ['bot','crawler','spider','scraper','automation','selenium','phantomjs','puppeteer','playwright','headless','webdriver'];
    const isBot = botKeywords.some(k => ua.includes(k));
    const results = {
      isSuspicious: false,
      reasons: [],
      isEmulator: false,
      isUsingVPN: false,
      isBot,
      isHeadless,
      hasFakeUserAgent: false,
      pluginsAnomaly: false,
      webDriverDetected: !!navigator.webdriver,
      suspiciousBehavior: {}
    };
    if (isBot) {
      results.isSuspicious = true;
      results.reasons.push('Detected bot behavior');
    }
    if (isHeadless) {
      results.isSuspicious = true;
      results.reasons.push('Detected headless browser');
    }
    return results;
  }

  /**
   * 获取设备指纹
   */
  getDeviceFingerprint() {
    return this.deviceFingerprint;
  }

  /**
   * 获取设备信息
   */
  async getDeviceInfo() {
    return {
      userAgent: navigator.userAgent,
      language: navigator.language,
      platform: navigator.platform,
      cookieEnabled: navigator.cookieEnabled,
      doNotTrack: navigator.doNotTrack,
      screenResolution: `${screen.width}x${screen.height}`,
      screenColorDepth: screen.colorDepth,
      timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
      fingerprint: this.deviceFingerprint,
      sessionId: this.sessionId,
      isMobile: this.isMobile(),
      browser: this.getBrowserInfo(),
      os: this.getOSInfo()
    };
  }

  /**
   * 发送请求
   */
  async request(endpoint, data = {}) {
    try {
      const url = this.config.cors.enabled && this.config.cors.proxy 
        ? this.config.cors.proxy + endpoint 
        : this.config.apiUrl + endpoint;
      
      // 压缩数据
      let requestData = data;
      if (this.config.performance.enableCompression) {
        requestData = { compressed: this.compress(data) };
      }
      
      const options = {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-API-Key': this.config.apiKey,
          'X-Session-ID': this.sessionId,
          'X-Fingerprint': this.deviceFingerprint,
          'X-SDK-Version': '1.0.0'
        },
        body: JSON.stringify(requestData),
        signal: AbortSignal.timeout(this.config.timeout)
      };
      
      const response = await fetch(url, options);
      
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }
      
      const result = await response.json();
      
      if (result.code !== 0) {
        throw new Error(result.message || 'Request failed');
      }
      
      return result;
      
    } catch (error) {
      if (error.name === 'AbortError') {
        throw new Error('Request timeout');
      }
      
      this.log('Request failed:', error);
      throw error;
    }
  }

  /**
   * 缓存操作
   */
  getCache(key) {
    try {
      const cached = this.cache.get(key);
      if (cached && cached.expires > Date.now()) {
        return cached.data;
      }
      this.cache.delete(key);
      return null;
    } catch (e) {
      return null;
    }
  }

  setCache(key, data, timeout = 3600000) {
    try {
      this.cache.set(key, {
        data: data,
        expires: Date.now() + timeout
      });
    } catch (e) {
      // 忽略缓存错误
    }
  }

  /**
   * 事件监听
   */
  on(event, callback) {
    if (!this.eventListeners[event]) {
      this.eventListeners[event] = [];
    }
    this.eventListeners[event].push(callback);
  }

  off(event, callback) {
    if (this.eventListeners[event]) {
      this.eventListeners[event] = this.eventListeners[event].filter(cb => cb !== callback);
    }
  }

  emit(event, data) {
    if (this.eventListeners[event]) {
      this.eventListeners[event].forEach(callback => {
        try {
          callback(data);
        } catch (e) {
          this.log('Event callback error:', e);
        }
      });
    }
  }

  /**
   * 日志记录
   */
  log(...args) {
    if (this.config.debug) {
      console.log('[XappTool]', ...args);
    }
  }

  /**
   * 其他辅助方法
   */
  isMobile() {
    return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
  }

  getBrowserInfo() {
    const ua = navigator.userAgent;
    let browser = 'Unknown';
    let version = 'Unknown';
    
    if (ua.indexOf('Chrome') > -1) {
      browser = 'Chrome';
      version = ua.match(/Chrome\/(\d+\.\d+)/)?.[1] || 'Unknown';
    } else if (ua.indexOf('Firefox') > -1) {
      browser = 'Firefox';
      version = ua.match(/Firefox\/(\d+\.\d+)/)?.[1] || 'Unknown';
    } else if (ua.indexOf('Safari') > -1) {
      browser = 'Safari';
      version = ua.match(/Version\/(\d+\.\d+)/)?.[1] || 'Unknown';
    } else if (ua.indexOf('Edge') > -1) {
      browser = 'Edge';
      version = ua.match(/Edge\/(\d+\.\d+)/)?.[1] || 'Unknown';
    }
    
    return { browser, version };
  }

  getOSInfo() {
    const ua = navigator.userAgent;
    let os = 'Unknown';
    let version = 'Unknown';
    
    if (ua.indexOf('Windows NT') > -1) {
      os = 'Windows';
      version = ua.match(/Windows NT (\d+\.\d+)/)?.[1] || 'Unknown';
    } else if (ua.indexOf('Mac OS X') > -1) {
      os = 'macOS';
      version = ua.match(/Mac OS X (\d+[_\.]\d+)/)?.[1] || 'Unknown';
    } else if (ua.indexOf('Android') > -1) {
      os = 'Android';
      version = ua.match(/Android (\d+\.\d+)/)?.[1] || 'Unknown';
    } else if (ua.indexOf('iOS') > -1 || ua.indexOf('iPhone') > -1 || ua.indexOf('iPad') > -1) {
      os = 'iOS';
      version = ua.match(/OS (\d+[_\.]\d+)/)?.[1] || 'Unknown';
    }
    
    return { os, version };
  }

  checkPrivacyCompliance() {
    // GDPR 合规检查
    if (this.config.privacy.gdpr.enabled) {
      const consent = localStorage.getItem('xapptool_gdpr_consent');
      if (!consent) {
        throw new Error('GDPR consent required');
      }
    }
    
    // CCPA 合规检查
    if (this.config.privacy.ccpa.enabled) {
      const doNotSell = localStorage.getItem('xapptool_ccpa_do_not_sell');
      if (doNotSell === 'true') {
        throw new Error('CCPA do not sell preference set');
      }
    }
  }

  checkBrowserCompatibility() {
    const compatibility = {
      isSupported: true,
      reason: '',
      features: {
        localStorage: !!window.localStorage,
        sessionStorage: !!window.sessionStorage,
        indexedDB: !!window.indexedDB,
        fetch: !!window.fetch,
        promise: typeof Promise !== 'undefined',
        geolocation: !!navigator.geolocation
      }
    };
    
    // 检查必需功能
    const requiredFeatures = ['localStorage', 'fetch', 'promise'];
    for (const feature of requiredFeatures) {
      if (!compatibility.features[feature]) {
        compatibility.isSupported = false;
        compatibility.reason = `Required feature not supported: ${feature}`;
        break;
      }
    }
    
    return compatibility;
  }

  startCacheCleanup() {
    setInterval(() => {
      const now = Date.now();
      for (const [key, value] of this.cache.entries()) {
        if (value.expires <= now) {
          this.cache.delete(key);
        }
      }
    }, 60000);
  }

  startBatchProcessor() {
    setInterval(() => {
      if (this.requestQueue.length > 0) {
        const batch = this.requestQueue.splice(0, this.config.performance.batchSize);
        this.processBatchRequest(batch);
      }
    }, this.config.performance.batchInterval);
  }

  async processBatchRequest(requests) {
    try {
      const response = await this.request('/api/v1/batch', { requests });
      this.log('Batch request processed:', response);
    } catch (error) {
      this.log('Batch request failed:', error);
    }
  }

  // 版本信息
  getVersion() {
    return '1.0.0';
  }

  // 调试信息
  getDebugInfo() {
    return {
      version: this.getVersion(),
      isInitialized: this.isInitialized,
      deviceFingerprint: this.deviceFingerprint,
      sessionId: this.sessionId,
      config: this.config,
      cacheSize: this.cache.size,
      queueSize: this.requestQueue.length
    };
  }
}

// React Hooks
export const useXappTool = (options = {}) => {
  const [xappTool, setXappTool] = useState(null);
  const [isInitialized, setIsInitialized] = useState(false);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState(null);
  const [installParams, setInstallParams] = useState(null);
  const [deviceInfo, setDeviceInfo] = useState(null);
  
  const xappToolRef = useRef(null);

  useEffect(() => {
    const initXappTool = async () => {
      try {
        setIsLoading(true);
        setError(null);
        
        const sdk = new XappToolReact(options);
        xappToolRef.current = sdk;
        setXappTool(sdk);
        
        await sdk.init();
        setIsInitialized(true);
        
        // 获取安装参数
        const params = await sdk.getInstallParams();
        setInstallParams(params);
        
        // 获取设备信息
        const device = await sdk.getDeviceInfo();
        setDeviceInfo(device);
        
      } catch (err) {
        setError(err.message);
        console.error('XappTool initialization failed:', err);
      } finally {
        setIsLoading(false);
      }
    };

    initXappTool();

    return () => {
      if (xappToolRef.current) {
        xappToolRef.current = null;
      }
    };
  }, [JSON.stringify(options)]);

  const generateInvitationLink = useCallback(async (invitationOptions = {}) => {
    if (!xappTool || !isInitialized) {
      throw new Error('XappTool not initialized');
    }
    
    try {
      return await xappTool.generateInvitationLink(invitationOptions);
    } catch (err) {
      setError(err.message);
      throw err;
    }
  }, [xappTool, isInitialized]);

  const getDeviceFingerprint = useCallback(() => {
    return xappTool?.getDeviceFingerprint() || null;
  }, [xappTool]);

  const getDebugInfo = useCallback(() => {
    return xappTool?.getDebugInfo() || null;
  }, [xappTool]);

  return {
    xappTool,
    isInitialized,
    isLoading,
    error,
    installParams,
    deviceInfo,
    generateInvitationLink,
    getDeviceFingerprint,
    getDebugInfo
  };
};

export const withXappTool = (Component, options = {}) => {
  return function WrappedComponent(props) {
    const xappToolData = useXappTool(options);
    return React.createElement(Component, { ...props, xappToolData });
  };
};

export default XappToolReact;